﻿using CommonBehaviors.Actions;
using Styx;
using Styx.Helpers;
using Styx.Logic.Combat;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using TreeSharp;
using Action = TreeSharp.Action;
using Styx.Combat.CombatRoutine;


namespace Altarboy
{
    class AfflictionWarlock
    {

        #region Delegates
        public delegate bool SimpleBoolReturnDelegate(object context);
        public delegate WoWUnit UnitSelectionDelegate(object context);
        #endregion

        // Current Player   
        public static LocalPlayer Me { get { return StyxWoW.Me; } }
        public static string CheckMana { get { return Me.ManaPercent.ToString("###"); } }
        

        public static Composite Target()
        {
            return new PrioritySelector(

             new Decorator(ret => AltarboySettings.Instance.EnableTargeting,
                 new Sequence(
                //cache possible targets
                     new Action(delegate
            {
                TargetManager.AcquireTargets();
            }),
                     new PrioritySelector(
                        TargetManager.SelectFocusTarget(),
                //TargetManager.SelectExecuteTarget(),
                //TargetManager.SelectMultiDotTarget(),
                        TargetManager.SelectLeadersTarget(),
                        TargetManager.SelectClosestTarget()

                     ),
                //reset target cache
                       new Action(delegate
            {
                TargetManager.ResetTargets();
            }),

                     //If we still dont have a target here, fail this shit.
                      new Decorator(ret => (TargetManager.ActiveTarget == null), new ActionAlwaysFail())
                  )
              ),

              TargetManager.SelectUserTarget()


            );
        }

        public static Composite Pull()
        {

            return AltarboyComposites.CastSpell("Corruption", ret => true, TargetManager.ActiveTarget);

        }

        public static Composite Combat()
        {
            return  new Sequence(

                //Select a target
                Target(),

                //Then kill it.
                new Decorator(
                      ret => TargetManager.ActiveTarget != null
                      && !CastManager.IsHymning()
                      && !Me.IsFalling
                      && !TargetManager.IsIgnoreTarget(TargetManager.ActiveTarget), //Added falling clause cause was killing me on Ragnaros.
                      SingleTargetDps()

                )

            );

        }

        #region Affliction Warlock DPS Composites

        private static Composite SingleTargetDps()
        {
            //Never Attack Anything That we shouldnt
            return new Decorator(
                ret => TargetManager.ShouldAttack(TargetManager.ActiveTarget),
                     new PrioritySelector(
                       AltarboyComposites.UseCoolDowns(), //cant seem to detect if a trinket can but used or not... gonna have to use user settings.
                       new Decorator(ret => AuraManager.HasAuraStacks("Molten Feather", 2, Me), NormalDpsRotation(ret => true)), // Alysrazor
                //new Decorator(ret => TargetManager.IsShackleTarget(TargetManager.ActiveTarget), ShackleTarget()),
                       new Decorator(ret => Me.IsMoving, MovementDps()),
                //new Decorator(ret => TargetManager.IsMindSpikeTarget(TargetManager.ActiveTarget), MindSpikeRotation()),
                       new Decorator(ret => !TargetManager.IsMindSpikeTarget(TargetManager.ActiveTarget), NormalDpsRotation(ret => true))
                      )
                );
        }

        private static Composite MovementDps()
        {
            return new PrioritySelector(

                 //Use Life Tap when low on mana.  Clean up with variables later
                 AltarboyComposites.CastSpellSimple("Life Tap", ret => WarlockComposites.ShouldLifeTap(TargetManager.ActiveTarget), Me),

                   // Make sure Corruption is up.  Will add some kind of implementation for rolling Banes here later.
                   AltarboyComposites.CastSpellSimple("Corruption", ret => (
                       AuraManager.GetAuraTimeLeft("Corruption", TargetManager.ActiveTarget, true).TotalSeconds <= .4)
                   , TargetManager.ActiveTarget),


                    //Free Shadow Bolt procs...
                    AltarboyComposites.CastSpellSimple("Shadow Bolt", ret =>
                        AuraManager.HasMyAura("Shadow Trance", Me),
                        TargetManager.ActiveTarget
                    ),

                    //This will spam cause its good dps...
                    AltarboyComposites.CastSpellSimple("Fel Flame", ret => Me.IsSafelyFacing(TargetManager.ActiveTarget), TargetManager.ActiveTarget)

            );
        }



        private static Composite NormalDpsRotation(SimpleBoolReturnDelegate extra)
        {

            // Altarboy.Logger.Slog(Color.Lime, "--- Single Target Max Dps Rotation  --- ");
            return new Sequence(

             //this is the stationary composite, so it shouldn't be an issue to face the target.
             new TreeSharp.Action(delegate { if (!Me.IsMoving && !Me.IsSafelyFacing(TargetManager.ActiveTarget)) { TargetManager.ActiveTarget.Face(); } }),

             new Decorator(
                 ret => extra(ret),


                  new PrioritySelector(

                    //Life Tap if out of mana.
                    AltarboyComposites.CastSpellSimple("Life Tap", ret =>
                        WarlockComposites.ShouldLifeTap(TargetManager.ActiveTarget)
                    ),

                    //Demon Soul.
                    AltarboyComposites.CastSpellSimple("Demon Soul", ret =>
                        AuraManager.HasMyAura(AltarboySettings.Instance.KeyBuffWarlock, Me)
                    ),

                    ////Shadow Bolt opener, applying Shadow and Flame.
                //AltarboyComposites.CastDebuff("Shadow Bolt", ret => 
                //    !AuraManager.HasMyAura("Shadow and Flame", TargetManager.ActiveTarget), 
                //    TargetManager.ActiveTarget, "Shadow and Flame"
                //),

                    //Haunt                  
                    AltarboyComposites.CastSpellSimple("Haunt", ret =>
                        AuraManager.GetAuraTimeLeft("Haunt", TargetManager.ActiveTarget, true).TotalSeconds <= 2.1,
                        TargetManager.ActiveTarget
                     ),

                    //Unstable Affliction                  
                    AltarboyComposites.CastDebuffX("Unstable Affliction", ret =>
                        TargetManager.ShouldApplyUnstableAffliction() &&
                        AuraManager.GetAuraTimeLeft("Unstable Affliction", TargetManager.ActiveTarget, true).TotalSeconds <= 2.1,
                        TargetManager.ActiveTarget
                     ),


                    //Corruption                  
                    AltarboyComposites.CastSpellSimple("Corruption", ret =>
                        AuraManager.GetAuraTimeLeft("Corruption", TargetManager.ActiveTarget, true).TotalSeconds <= .4,
                        TargetManager.ActiveTarget
                     ),


                    //Bane of Doom - for very bad guys.
                    AltarboyComposites.CastSpellSimple("Bane of Doom", ret =>
                        TargetManager.ShouldApplyBane() &&
                        TargetManager.ShouldUseBaneOfDoom(TargetManager.ActiveTarget),
                      TargetManager.ActiveTarget, "High health target"
                    ),

                    //Bane of Agony - for not so bad guys.
                    AltarboyComposites.CastSpellSimple("Bane of Agony", ret =>
                        TargetManager.ShouldApplyBane() &&
                        !TargetManager.ShouldUseBaneOfDoom(TargetManager.ActiveTarget) &&
                        AuraManager.GetAuraTimeLeft("Bane of Agony", TargetManager.ActiveTarget, true).TotalSeconds <= .4,
                      TargetManager.ActiveTarget, "Solo or Target will die soon"
                    ),


                    //CotE                  
                    AltarboyComposites.CastSpellSimple("Curse of the Elements", ret =>
                        AuraManager.GetAuraTimeLeft("Curse of the Elements", TargetManager.ActiveTarget, true).TotalSeconds <= .4,
                        TargetManager.ActiveTarget
                     ),

                    //Drain Life if I'm in trouble.
                    AltarboyComposites.CastSpellSimple("Drain Life", ret => (
                        Me.HealthPercent <= 40),
                      TargetManager.ActiveTarget, "Low Health"
                    ),

                    //Free Shadow Bolt procs...
                    AltarboyComposites.CastSpellSimple("Shadow Bolt", ret =>
                        AuraManager.HasMyAura("Shadow Trance", Me),
                        TargetManager.ActiveTarget, "Instant Cast"
                    ),


                    //Drain Soul at Low Health.
                    AltarboyComposites.CastSpellSimple("Drain Soul", ret => (
                        TargetManager.ActiveTarget.HealthPercent <= 25),
                      TargetManager.ActiveTarget, "Target below 25% health"
                    ),

                    //Shadowflame if in range.
                    AltarboyComposites.CastSpellSimple("Shadowflame", ret => (true),
                      TargetManager.ActiveTarget, "Target in Range"
                    ),


                    //Shadow Bolt filler.
                    AltarboyComposites.CastSpellSimple("Shadow Bolt", ret => (true),
                      TargetManager.ActiveTarget
                    )

                 )
            )

          );

        }




        #endregion



    }
}
